﻿using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IsoStorageFacade_WP7_Tests
{
    [TestClass]
    public class Test_Sys_IO_PSDirectory
    {
        private const string RootFolder = @"\Isolated\";
        private const string TestDirName = "test";

        private static string[] GetRootDirNames()
        {
            return IsolatedStorageFile.GetUserStoreForApplication().GetDirectoryNames(RootFolder);
        }

        [TestInitialize]
        public void setup()
        {
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                store.CreateDirectory(RootFolder + TestDirName);
            }
        }

        [TestCleanup]
        public void teardown()
        {
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                store.DeleteDirectory(RootFolder + TestDirName);
                PSDirectory.SetCurrentDirectory(@"\");
            }
        }

        [TestMethod]
        public void Get_Dir_Names_Should_Get_At_Least_When_Called_On_Root()
        {
            //Add1DirInRoot();
            try
            {
                var names = PSDirectory.GetDirectories(@"\");
                Assert.IsNotNull(names, "GetDirectories should not be null");
                Assert.IsTrue(names.Length > 0, "GetDirectories should return more than 1 dir");
                Assert.IsTrue(names.Where(name => name.Contains(RootFolder)).Count() > 0, "GetDirectories should contain our test directory");
                Assert.IsTrue(names.Contains(RootFolder) || names.Contains(RootFolder + @"\"), "GetDirectories Should contain RootFolder directory");
            }
            finally
            {
                //RemoveAddedDir();
            }
        }

        [TestMethod]
        public void Get_Dir_Names_Should_Get_No_Records_When_Called_On_Test_SubDir()
        {
            //Add1DirInRoot();
            try
            {
                var names = PSDirectory.GetDirectories(RootFolder + TestDirName + @"\");
                Assert.IsNotNull(names, "GetDirectories should not be null");
                Assert.IsTrue(names.Length == 0, "GetDirectories should return no values (our dir should be empty)");
                Assert.IsFalse(names.Where(name => name.Contains(TestDirName)).Count() > 0, "GetDirectories should not contain our test directory");
                Assert.IsFalse(names.Contains(RootFolder + TestDirName) || names.Contains(RootFolder + TestDirName + @"\"), "GetDirectories Should Not contain \test directory");
            }
            finally
            {
                //RemoveAddedDir();
            }
        }

        [TestMethod]
        public void Creating_A_Directory_Should_Result_In_Directory_Created()
        {
            try
            {
                var result = PSDirectory.CreateDirectory(RootFolder + "Test1");
                Assert.IsNotNull(result, "result should not be null");
                Assert.IsTrue(result.Name.Length > 1, "result name should not be empty");
                Assert.IsTrue(result.Name.Contains("Test1"), "result name Should contain test1 directory");

                var names = IsolatedStorageFile.GetUserStoreForApplication().GetDirectoryNames(RootFolder);
                Assert.IsNotNull(names, "GetDirectories should not be null");
                Assert.IsTrue(names.Length > 1, "GetDirectories should return more than 1 value");
                Assert.IsTrue(names.Where(name => name.Contains("Test1")).Count() > 0, "GetDirectories should contain our test directory");
                Assert.IsTrue(names.Contains("Test1"), @"GetDirectories Should contain \test1 directory");

                PSDirectory.SetCurrentDirectory(RootFolder);
                result = PSDirectory.CreateDirectory("Test2");
                Assert.IsNotNull(result, "result should not be null");
                Assert.IsTrue(result.Name.Length > 1, "result name should not be empty");
                Assert.IsTrue(result.Name.Contains("Test2"), "result name Should contain test1 directory");

                names = IsolatedStorageFile.GetUserStoreForApplication().GetDirectoryNames(RootFolder);
                Assert.IsNotNull(names, "GetDirectories (workingDir) should not be null");
                Assert.IsTrue(names.Length > 2, "GetDirectories (workingDir) should return more than 1 value");
                Assert.IsTrue(names.Where(name => name.Contains("Test2")).Count() > 0, "GetDirectories (workingDir) should contain our test directory");
                Assert.IsTrue(names.Contains("Test2"), @"GetDirectories (workingDir) Should contain \test2 directory");
            }
            finally
            {
                try { IsolatedStorageFile.GetUserStoreForApplication().DeleteDirectory(RootFolder + "Test1"); }
                catch (Exception ex) { }
                try { IsolatedStorageFile.GetUserStoreForApplication().DeleteDirectory(RootFolder + "Test2"); }
                catch (Exception ex) { }
            }
        }

        [TestMethod]
        public void Deleting_A_Directory_Should_Result_In_Directory_Removed()
        {
            try
            {
                IsolatedStorageFile.GetUserStoreForApplication().CreateDirectory(RootFolder + "Test1");
                var names1 = GetRootDirNames();
                Assert.IsNotNull(names1, "GetDirectories should not be null");
                Assert.IsTrue(names1.Length > 1, "GetDirectories should return more than 1 value");

                PSDirectory.Delete(RootFolder + "Test1");

                var names = GetRootDirNames();
                Assert.IsNotNull(names, "GetDirectories should not be null");
                Assert.IsTrue(names.Length > 0, "GetDirectories should return at least 1 value (our default)");
                Assert.IsFalse(names.Where(name => name.Contains("Test1")).Count() > 0, "GetDirectories should not contain our test1 directory");
                Assert.IsFalse(names.Contains("Test1"), "GetDirectories Should Not contain Test1 directory");

                IsolatedStorageFile.GetUserStoreForApplication().CreateDirectory(RootFolder + "Test1");
                PSDirectory.SetCurrentDirectory(RootFolder);
                PSDirectory.Delete("Test1");

                names = GetRootDirNames();
                Assert.IsNotNull(names, "GetDirectories (WorkingDir) should not be null");
                Assert.IsTrue(names.Length > 0, "GetDirectories (WorkingDir) should return at least 1 value (our default)");
                Assert.IsFalse(names.Where(name => name.Contains("Test1")).Count() > 0, "GetDirectories (WorkingDir) should not contain our test1 directory");
                Assert.IsFalse(names.Contains("Test1"), "GetDirectories (WorkingDir) Should Not contain Test1 directory");
            }
            finally
            {
                if (IsolatedStorageFile.GetUserStoreForApplication().DirectoryExists(RootFolder + "Test1"))
                {
                    IsolatedStorageFile.GetUserStoreForApplication().DeleteDirectory(RootFolder + "Test1");
                }
            }
        }

        [TestMethod]
        public void Exists_Should_Return_True_When_A_Folder_Exists_And_False_When_It_Doesnt()
        {
            try
            {
                Assert.IsTrue(PSDirectory.Exists(RootFolder + TestDirName), "test folder should exist");
                Assert.IsFalse(PSDirectory.Exists("zzzzzz" + TestDirName), "non existent folder should not exist (WorkingDir)");

                PSDirectory.SetCurrentDirectory(RootFolder);
                Assert.IsTrue(PSDirectory.Exists(TestDirName), "test folder should exist (WorkingDir)");
                Assert.IsFalse(PSDirectory.Exists("zzzzzz" + TestDirName), "non existent folder should not exist (WorkingDir)");
            }
            finally
            {
            }
        }

        [TestMethod]
        public void Get_Current_Directory_Should_Return_Last_Set_Folder()
        {
            try
            {
                // Root at first
                Assert.IsTrue(PSDirectory.GetCurrentDirectory() == @"\", "Get Dir By default should be root");
                PSDirectory.SetCurrentDirectory(RootFolder + TestDirName);
                Assert.IsTrue(PSDirectory.GetCurrentDirectory() == RootFolder + TestDirName || PSDirectory.GetCurrentDirectory() == RootFolder + TestDirName + @"\" ||
                              PSDirectory.GetCurrentDirectory() == RootFolder + TestDirName || PSDirectory.GetCurrentDirectory() == RootFolder + TestDirName + @"\", "Get Dir after setting to test should return test");
            }
            finally
            {
                PSDirectory.SetCurrentDirectory(@"\");
            }
        }

        //TODO: need to add sme tests to make file actions also go relative
        [TestMethod]
        public void When_Getting_File_System_Entries_On_Root_In_Our_Test_Env_Should_Only_Return_1_Dir()
        {
            var dir = PSDirectory.GetFileSystemEntries(RootFolder);
            Assert.IsTrue(dir.Length > 0, "Should return at least our test directory when NOT using a filter string");
            Assert.IsTrue(typeof(AbstractFileSystemInfo).IsInstanceOfType(dir[0]), "GetFileSystemInfo (no search) should return an array of AbstractFileSystemInfo");
            var dirs = PSDirectory.GetFileSystemEntries(RootFolder, "tes*");
            Assert.IsTrue(dirs.Length > 0, "Should only return our test directory when using a filter string");
            Assert.IsTrue(typeof(AbstractFileSystemInfo).IsInstanceOfType(dir[0]), "GetFileSystemInfo (with search) should return an array of AbstractFileSystemInfo");
            var dir3 = PSDirectory.GetFileSystemEntries(RootFolder + TestDirName + @"\");
            Assert.IsTrue(dir3.Length == 0, "Should only return nothing when looking at the test subdir");
            var dir4 = PSDirectory.GetFileSystemEntries(RootFolder + TestDirName + @"\", "zzz*");
            Assert.IsTrue(dir4.Length == 0, "Should only return nothing when looking (2nd) at the test subdir");
        }

        [TestMethod]
        public void When_Getting_Dir_Root_Should_Always_be_Slash()
        {
            Assert.AreEqual(@"\", PSDirectory.GetDirectoryRoot(), @"Should only return \");
        }
    }
}